﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports Newtonsoft.Json
Imports roncliProductions.LibWowArmory.Enums
Imports roncliProductions.LibWowArmory.Extensions
Imports roncliProductions.LibWowArmory.Internationalization
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Globalization
Imports System.Linq

Namespace roncliProductions.LibWowArmory.Guild

    ''' <summary>
    ''' A class that retrieves guild profile information from the Blizzard WoW API.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class GuildProfile
        Inherits WowArmoryData

        Private gpGuild As New Schema.guild

#Region "WowArmoryData Overrides"

        Protected Overrides ReadOnly Property URI As Uri
            Get
                QueryString.Clear()
                If Not String.IsNullOrWhiteSpace(FieldList) Then
                    QueryString.Add("fields", FieldList)
                End If
                Return New Uri(String.Format(CultureInfo.InvariantCulture, "/api/wow/guild/{0}/{1}", Options.Realm, Options.Name), UriKind.Relative)
            End Get
        End Property

        Protected Overrides ReadOnly Property CacheKey As String
            Get
                Return String.Format(CultureInfo.InvariantCulture, "LibWowArmory.GuildProfile.{0}.{1}.{2}", Options.Realm, Options.Name, FieldList)
            End Get
        End Property

#End Region

#Region "Properties"

#Region "Public"

        ''' <summary>
        ''' The options for looking up guild profile information.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Options As New GuildProfileOptions

        Private gGuild As Guild
        ''' <summary>
        ''' Guild profile information as returned from the Blizzard WoW API.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Guild As Guild
            Get
                Return gGuild
            End Get
        End Property

#End Region

#Region "Private"

        Private ReadOnly Property FieldList As String
            Get
                Dim lstFields As New List(Of String)
                If Options.Members Then lstFields.Add("members")
                If Options.Achievements Then lstFields.Add("achievements")
                Return String.Join(",", lstFields)
            End Get
        End Property

#End Region

#End Region

#Region "Methods"

#Region "Public"

#Region "Constructors"

        ''' <summary>
        ''' A default constructor to retrieve guild profile information from the Blizzard WoW API.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
        End Sub

        ''' <summary>
        ''' A constructor to retrieve a guild's profile.
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <param name="strName"></param>
        ''' <remarks></remarks>
        Public Sub New(strRealm As String, strName As String)
            Options.Realm = strRealm
            Options.Name = strName
            Load()
        End Sub

        ''' <summary>
        ''' A constructor to retrieve guild profile information for a specific region and language from the Blizzard WoW API.
        ''' </summary>
        ''' <param name="rRegion"></param>
        ''' <param name="lLanguage"></param>
        ''' <remarks></remarks>
        Public Sub New(rRegion As Region, lLanguage As Language)
            Region = rRegion
            Language = lLanguage
        End Sub

        ''' <summary>
        ''' A constructor to retrieve a guild's profile for a specific region and language.
        ''' </summary>
        ''' <param name="rRegion"></param>
        ''' <param name="lLanguage"></param>
        ''' <param name="strRealm"></param>
        ''' <param name="strName"></param>
        ''' <remarks></remarks>
        Public Sub New(rRegion As Region, lLanguage As Language, strRealm As String, strName As String)
            Me.New(rRegion, lLanguage)
            Options.Realm = strRealm
            Options.Name = strName
            Load()
        End Sub

#End Region

        ''' <summary>
        ''' Loads the guild profile.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            MyBase.Retrieve()
            gpGuild = CType(JsonConvert.DeserializeObject(Data, GetType(Schema.guild)), Schema.guild)
            gGuild = New Guild(
                gpGuild.lastModified.BlizzardTimestampToUTC(),
                gpGuild.name,
                gpGuild.realm,
                gpGuild.level,
                CType(gpGuild.side, Side),
                gpGuild.achievementPoints,
                If(gpGuild.achievements Is Nothing, Nothing, SetAchievements(gpGuild.achievements)),
                If(gpGuild.members Is Nothing OrElse gpGuild.members.Count = 0, Nothing,
                    (From m In gpGuild.members
                    Select New Member(
                        New Character(
                            m.character.name,
                            m.character.realm,
                            m.character.class.GetClass(Region, Language),
                            m.character.race.GetRace(Region, Language),
                            CType(m.character.gender, Gender),
                            m.character.level,
                            m.character.achievementPoints,
                            m.character.thumbnail
                            ),
                        m.rank
                        )
                    ).ToCollection()
                    ),
                New Emblem(
                    gpGuild.emblem.icon,
                    gpGuild.emblem.iconColor.ArgbHexToColor(),
                    gpGuild.emblem.border,
                    gpGuild.emblem.borderColor.ArgbHexToColor(),
                    gpGuild.emblem.backgroundColor.ArgbHexToColor()
                    )
                )
        End Sub

#End Region

#Region "Private"

        Private Shared Function SetAchievements(aAchievements As Schema.achievements) As Achievements
            Dim colAchievements As New Collection(Of Achievement)
            Dim enumAchievement = aAchievements.achievementsCompleted.GetEnumerator()
            Dim enumAchievementTimestamp = aAchievements.achievementsCompletedTimestamp.GetEnumerator()
            While enumAchievement.MoveNext() And enumAchievementTimestamp.MoveNext()
                colAchievements.Add(New Achievement(CInt(enumAchievement.Current), CLng(enumAchievementTimestamp.Current).BlizzardTimestampToUTC()))
            End While

            Dim colCriteria As New Collection(Of Criteria)
            Dim enumCriteria = aAchievements.criteria.GetEnumerator()
            Dim enumCriteriaQuantity = aAchievements.criteriaQuantity.GetEnumerator()
            Dim enumCriteriaTimestamp = aAchievements.criteriaTimestamp.GetEnumerator()
            Dim enumCriteriaCreated = aAchievements.criteriaCreated.GetEnumerator()
            While enumCriteria.MoveNext() And enumCriteriaCreated.MoveNext() And enumCriteriaQuantity.MoveNext() And enumCriteriaTimestamp.MoveNext()
                colCriteria.Add(New Criteria(
                                CInt(enumCriteria.Current),
                                CLng(enumCriteriaQuantity.Current),
                                CLng(enumCriteriaTimestamp.Current).BlizzardTimestampToUTC(),
                                CLng(enumCriteriaCreated.Current).BlizzardTimestampToUTC()
                                ))
            End While

            Return New Achievements(colAchievements, colCriteria)
        End Function

#End Region

#End Region

    End Class

End Namespace